﻿
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Collections;

namespace FilterGrid
{
    /// <summary>
    /// Filter grid is a extended gridview with filtering and sorting options
    /// </summary>

    public class IntegerColumn : DataControlField
    {

        protected override DataControlField CreateField()
        {
            throw new NotImplementedException();
        }
    }


    [ToolboxData("<{0}:FilterGrid runat=server></{0}:FilterGrid>")]
    public class FilterGrid : GridView
    {

        #region Declaration

        SqlDataSource ds; //Declaring the datasource
        #endregion

        #region Properties
        //[Bindable(true)]
        //[Category("Appearance")]
        //[DefaultValue("")]
        //[Localizable(false)]
        //public string Text
        //{
        //    get
        //    {
        //        String s = (String)ViewState["Text"];
        //        return ((s == null) ? "[" + this.ID + "]" : s);
        //    }

        //    set
        //    {
        //        ViewState["Text"] = value;
        //    }
        //}
        //[Bindable(false)]
        //[Category("Behaviour")]
        //[DefaultValue(true)]
        //[Localizable(false)]
        //public bool DoubleClickToSelect
        //{
        //    get
        //    {
        //        bool s;
        //        if (ViewState["DoubleClickToSelect"] != null)
        //        {
        //            s = (bool)ViewState["DoubleClickToSelect"];
        //        }
        //        else
        //        {
        //            s = false;
        //        }
        //        return s;
        //    }

        //    set
        //    {
        //        ViewState["DoubleClickToSelect"] = value;
        //    }
        //}


        #endregion

        #region overriden OnDataboundEvent
        /// <summary>
        /// Overide the OnDataboundEvent
        /// </summary>
        /// <param name="e"></param>
        protected override void OnDataBound(EventArgs e)
        {
            base.OnDataBound(e);  ///Calling the Parent gridview class event;

            this.ShowHeader = true;   ///Shows the gridview header always


            foreach (DataControlField col in this.Columns)
            {

                if (col is BoundField) ///Loops through all the bounded fields
                {
                    string colname = col.SortExpression;
                    TextBox txt;
                    if (FindControl("txt" + colname) != null)
                    {
                        //Finds the filter textbox in all the columns and replace it with the values in view state
                        txt = (TextBox)FindControl("txt" + colname);

                        if (ViewState["txt" + colname].ToString() != string.Empty)
                            txt.Text = ViewState["txt" + colname].ToString();
                    }
                }
            }



        }
        #endregion

        #region Overriden OnRowCreated

        /// <summary>
        /// Overrided Event for OnRowCreated
        /// </summary>
        /// <param name="e"></param>
        protected override void OnRowCreated(GridViewRowEventArgs e)
        {
            base.OnRowCreated(e);  //Calls the base class event


            if (e.Row.RowType == DataControlRowType.Header)  //Checks whether its header
            {

                foreach (TableCell t in e.Row.Cells)        //Loops to each cells in header row
                {
                    DataControlFieldHeaderCell headercell = (DataControlFieldHeaderCell)t;
                    Table tab = new Table();
                    TableRow tr1 = new TableRow();
                    TableCell tc1 = new TableCell();

                    ///Adds label for Header text
                    LinkButton l = new LinkButton();
                    l.ID = "lbl" + headercell.ContainingField.SortExpression;
                    l.Text = t.Text;
                    l.Font.Bold = true;
                    l.ForeColor = System.Drawing.Color.White;
                    l.Click += new EventHandler(desc_Click);
                    t.Controls.Add(l);

                    ///Adds search textbox for the columns
                    TextBox _txt = new TextBox();
                    _txt.ID = "txt" + headercell.ContainingField.SortExpression;
                    _txt.BorderWidth = new Unit(0, UnitType.Pixel);
                    _txt.Width = new Unit(100, UnitType.Percentage);
                    _txt.Style.Add("min-width", "25px");
                    _txt.CssClass = "txtbox " + headercell.ContainingField.SortExpression;

                    //  _txt.TextChanged += new EventHandler(TextBox1_TextChanged);
                    //   _txt.AutoPostBack = true;
                    // if (ViewState[_txt.ID] != null)
                    //     _txt.Text = ViewState[_txt.ID].ToString();


                    t.Controls.Add(_txt);
                    t.HorizontalAlign = HorizontalAlign.Center;


                }
            }
            if (e.Row.RowType == DataControlRowType.DataRow)  //Checks whether its header
            {

                foreach (TableCell t in e.Row.Cells)        //Loops to each cells in header row
                {
                    DataControlFieldCell headercell = (DataControlFieldCell)t;
                    Table tab = new Table();
                    TableRow tr1 = new TableRow();
                    TableCell tc1 = new TableCell();


                    t.CssClass = headercell.ContainingField.SortExpression; 
                   



                }
            }




        }
        #endregion

        #region OnPagePreLoad
        /// <summary>
        /// Override event for OnPagePreLoad
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected override void OnPagePreLoad(object sender, EventArgs e)
        {
            string script = "";
            string ClientID = "ctl00$" + this.ClientID.Replace('_', '$');   ///Replaces the ClientID with Javascript format
            ///Forcing postback for gridSelecting Event
            //string script = @"<script language=""javascript"" type=""text/javascript""> $(document).ready(function () {            $('#" + this.ClientID + "').ready(function (event) {                $('#" + this.ClientID + "').find('tr').dblclick(function () {                   var index = $('#" + this.ClientID + "').find('tr').index(this);                    if (index > 0) {                        var index = parseInt(index) - 1;                        __doPostBack('" + ClientID + "', 'Select$' + index);                    }                });            });        }); </script> ";
            //if (Convert.ToBoolean(ViewState["DoubleClickToSelect"]) == true)
            //{
            //    script = @"<script language=""javascript"" type=""text/javascript"">        $('#" + this.ClientID + "').ready(function (event) {        $('#" + this.ClientID + "').find('tr').dblclick(function () {                   var index = $('#" + this.ClientID + "').find('tr').index(this);                    if (index > 0) {                        var index = parseInt(index) - 1;                        __doPostBack('" + ClientID + "', 'Select$' + index);                    }                });            });    </script> ";
            //    script += @"<script language=""javascript"" type=""text/javascript"">        $('#" + this.ClientID + "').ready(function (event) {       var style = '';                var boldStyle = ';font-weight:bold;';                       $('#" + this.ClientID + "').find('tr').click(function () {                        jQuery(this).parent().find('tr').each(function () {                       var s = jQuery(this).attr('style').replace(boldStyle, '');                        jQuery(this).attr('style', s);                                          });                    style = jQuery(this).attr('style');                    jQuery(this).attr('style', style + boldStyle);                });             }); </script>";
            //}
            //else
            //    script = @"<script language=""javascript"" type=""text/javascript"">     $(document).ready(function () {     $('#" + this.ClientID + "').ready(function (event) {         $('#" + this.ClientID + "').find('tr').click(function () {                   var index = $('#" + this.ClientID + "').find('tr').index(this);                    if (index > 0) {                        var index = parseInt(index) - 1;                        __doPostBack('" + ClientID + "', 'Select$' + index);                    }                });     });     });   </script> ";
            ///Script to bold text when it is selected
            //script += @"<script language=""javascript"" type=""text/javascript"">        $(document).ready(function () {            $('#" + this.ClientID + "').ready(function (event) {                var style = '';                var boldStyle = ';font-weight:bold;';                jQuery(this).find('tr').click(function () {                    jQuery(this).parent().find('tr').each(function () {                        var s = jQuery(this).attr('style').replace(boldStyle, '');                        jQuery(this).attr('style', s);                                          });                    style = jQuery(this).attr('style');                    jQuery(this).attr('style', style + boldStyle);                });            });        });    </script>";

            base.OnPagePreLoad(sender, e);  ///Calls the Base class event

            this.Style.Add("cursor", "pointer");
            this.Page.ClientScript.RegisterClientScriptBlock(Page.GetType(), this.ClientID, script);
            ///Adds the script to the page

        }
        #endregion

        #region TextchangedEvent for Textbox1
        /// <summary>
        /// Textchanged event for Filter grid
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void TextBox1_TextChanged(object sender, EventArgs e)
        {

            TextBox _txt = new TextBox();
            _txt = (TextBox)sender;         //Gets the textbox which raises the event
            Hashtable filter = new Hashtable();     //Creates a hashtable adding the filter text

            if (ViewState["filter"] != null)
                filter = (Hashtable)ViewState["filter"];// Checks whether the Hasttable already exists in viewstate and saves to filter object

            ViewState[_txt.ID] = _txt.Text;         //Gets the filter text and saves to the viewstate;

            string _key = _txt.ID.Remove(0, 3);
            if (filter.ContainsKey(_key))
                filter.Remove(_key);
            filter.Add(_key, _txt.Text); //Adds the search text to hash table 

            ViewState["filter"] = filter; //Assigns the filter hasttable to viewstate



            // Assigns the search text from viewstate to textbox;
            if (ViewState[_txt.ID].ToString() != string.Empty)
            {
                _txt.Text = ViewState[_txt.ID].ToString();
                _txt.Focus();
            }
            FilterIt();
        }

        #endregion

        #region OnPageIndexChanged Event
        protected override void OnPageIndexChanged(EventArgs e)
        {
            base.OnPageIndexChanged(e);
            FilterIt();




        }
        #endregion

        #region OnSorting Event
        protected override void OnSorting(GridViewSortEventArgs e)
        {
            base.OnSorting(e);
            FilterIt();
        }
        #endregion

        #region FilterIt
        private void FilterIt()
        {

            Hashtable filter = new Hashtable();     //Creates a hashtable adding the filter text

            if (ViewState["filter"] != null)
                filter = (Hashtable)ViewState["filter"];// Checks whether the Hasttable already exists in viewstate and saves to filter object
            string strFilter = " ";

            //Gets the filter text and saves to the viewstate;
            ds = (SqlDataSource)this.GetDataSource();//Gets the datasource of the Gridview for filtering
            ds.DataSourceMode = SqlDataSourceMode.DataSet;
            ds.EnableCaching = true;
            ds.CacheDuration = 1;

            ViewState["filter"] = filter;
            foreach (DictionaryEntry row in filter)  ///Loops through all the element in filter hasttable
            {

                ///Converts the values in hasttable to a query
                if (row.Value.ToString() != string.Empty)
                {
                    strFilter = strFilter + " CONVERT(" + row.Key.ToString() + ",System.String) like '%" + row.Value.ToString() + "%' and ";

                }

            }
            if (strFilter.EndsWith("and "))
            {
                strFilter = strFilter.Remove(strFilter.LastIndexOf("and"), 3);      ///Removes the last and if exists;
            }
            // ds.SelectCommand = "select * from (" + ds.SelectCommand + ") as tab where " + strFilter;
            ds.FilterExpression = strFilter;
            ds.DataBind(); //Binds the data to the SqlDatasource;

            // Assigns the search text from viewstate to textbox;
        }
        #endregion


        #region V0.1 Unused
        #region FindControlRecursive
        /// <summary>
        /// Method to find a control in a page
        /// </summary>
        /// <param name="ctrl"></param>
        /// <param name="id"></param>
        /// <returns></returns>

        public Control FindControlRecursive(Control ctrl, string id)
        {
            Control c = null;

            if (ctrl.ID == id)
            {
                c = ctrl;
            }
            else
            {
                foreach (Control childCtrl in ctrl.Controls)
                {

                    Control resCtrl = FindControlRecursive(childCtrl, id);
                    if (resCtrl != null)
                        c = resCtrl;
                }
            }

            return c;
        }
        #endregion


        #region GetGrid
        /// <summary>
        /// Method to GetGridView from a page
        /// </summary>
        /// <param name="ID">GridViewID</param>
        /// <returns>GridView</returns>

        private GridView GetGrid(string ID)
        {
            ///Passes the ID and the page to find the Gridview
            GridView grd = (GridView)FindControlRecursive(this.Page, this.ID);
            return grd;
        }
        #endregion

        #region Click event for Desc button
        /// <summary>
        /// Click event for Desc button 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void desc_Click(object sender, EventArgs e)
        {
            //Gets the button 
            LinkButton b = (LinkButton)sender;
            b.BorderWidth = new Unit(2, UnitType.Pixel);

            Label sortlbl = new Label();
            if (b.Parent.Controls.Contains(sortlbl))
                b.Parent.Controls.Remove(sortlbl);

            string col = b.ID.Remove(0, 3);
            GridView grd = GetGrid(this.ID); //Gets the Gridview

            if (grd.SortDirection == SortDirection.Ascending)
            {
                grd.Sort(col, SortDirection.Descending); //Sorts the gridview   


                sortlbl.Text = "˅";
            }
            else
            {
                grd.Sort(col, SortDirection.Ascending); //Sorts the gridview  
                sortlbl.Text = "˄";
            }

            //((Button)grd.FindControl("btnA" + col)).Visible = true;
            //b.Visible = false;


            b.Parent.Controls.Add(sortlbl);

        }
        #endregion

        #region Click event for asc button
        /// <summary>
        /// Click event for ascending button
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void asc_Click(object sender, EventArgs e)
        {
            ///Gets the button
            LinkButton b = (LinkButton)sender;
            b.BorderWidth = new Unit(2, UnitType.Pixel);
            string col = b.ID.Remove(0, 4);
            GridView grd = GetGrid(this.ID); ///Gets the Gridview
            grd.Sort(col, SortDirection.Ascending);//Sorts the gridview
            //((Button)grd.FindControl("btnD" + col)).Visible = true;
            //b.Visible = false;
            b.Font.Bold = true;

        }
        #endregion
        #endregion

    }
}
